package org.javahispano.javacup.tacticas.tacticas_aceptadas.Orange;

import org.javahispano.javacup.modelo.engine.SituacionPartido;
import org.javahispano.javacup.modelo.util.Posicion;
import org.javahispano.javacup.modelo.util.Constantes;
import org.javahispano.javacup.modelo.TacticaDetalle;
import org.javahispano.javacup.modelo.JugadorDetalle;
import org.javahispano.javacup.modelo.Tactica;
import org.javahispano.javacup.modelo.comando.Comando;
import org.javahispano.javacup.modelo.comando.ComandoIrA;
import org.javahispano.javacup.modelo.comando.ComandoGolpearBalon;
import org.javahispano.javacup.render.EstiloUniforme;
import java.awt.Color;
import org.javahispano.javacup.modelo.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class Orange implements Tactica {

    Posicion alineacion1[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(25.44055944055944, -27.556561085972852),
        new Posicion(-27.81818181818182, -27.31900452488688),
        new Posicion(9.272727272727272, -31.119909502262445),
        new Posicion(-10.461538461538462, -30.407239819004527),
        new Posicion(0.7132867132867133, -8.552036199095022),
        new Posicion(29.95804195804196, -4.276018099547511),
        new Posicion(-30.195804195804197, -3.800904977375566),
        new Posicion(-0.4755244755244755, 26.131221719457013),
        new Posicion(31.622377622377623, 21.855203619909503),
        new Posicion(-31.146853146853147, 21.380090497737555)
    };
    Posicion alineacion2[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(-11.16030534351145, -31.082089552238806),
        new Posicion(11.16030534351145, -31.6044776119403),
        new Posicion(27.251908396946565, -27.94776119402985),
        new Posicion(-29.84732824427481, -26.902985074626866),
        new Posicion(6.181818181818182, -18.054298642533936),
        new Posicion(-9.034965034965035, -19.95475113122172),
        new Posicion(30.67132867132867, -2.6131221719457014),
        new Posicion(-1.6643356643356644, -0.47511312217194573),
        new Posicion(1.902097902097902, -1.900452488687783),
        new Posicion(-31.384615384615387, -1.6628959276018098)
    };
    Posicion alineacion3[] = new Posicion[]{
        new Posicion(0.2595419847328244, -50.41044776119403),
        new Posicion(28.76923076923077, -30.88235294117647),
        new Posicion(-30.195804195804197, -29.694570135746606),
        new Posicion(-9.034965034965035, -30.6447963800905),
        new Posicion(9.986013986013985, -31.357466063348415),
        new Posicion(-4.755244755244756, -14.490950226244346),
        new Posicion(5.230769230769231, -14.015837104072398),
        new Posicion(-13.79020979020979, -4.276018099547511),
        new Posicion(11.888111888111888, -4.513574660633484),
        new Posicion(30.195804195804197, -3.5633484162895925),
        new Posicion(-31.622377622377623, -3.800904977375566)
    };

    class TacticaDetalleImpl implements TacticaDetalle {

        public String getNombre() {
            return "Orange";
        }

        public String getPais() {
            return "Holanda";
        }

        public String getEntrenador() {
            return "Maca";
        }

        public Color getColorCamiseta() {
            return new Color(255, 124, 0);
        }

        public Color getColorPantalon() {
            return new Color(255, 255, 255);
        }

        public Color getColorFranja() {
            return new Color(255, 255, 255);
        }

        public Color getColorCalcetas() {
            return new Color(255, 255, 255);
        }

        public Color getColorPortero() {
            return new Color(0, 0, 255);
        }

        public EstiloUniforme getEstilo() {
            return EstiloUniforme.SIN_ESTILO;
        }

        public Color getColorCamiseta2() {
            return new Color(0, 0, 0);
        }

        public Color getColorPantalon2() {
            return new Color(0, 0, 0);
        }

        public Color getColorFranja2() {
            return new Color(255, 255, 255);
        }

        public Color getColorCalcetas2() {
            return new Color(255, 255, 255);
        }

        public Color getColorPortero2() {
            return new Color(31, 67, 250);
        }

        public EstiloUniforme getEstilo2() {
            return EstiloUniforme.SIN_ESTILO;
        }

        class JugadorImpl implements JugadorDetalle {

            String nombre;
            int numero;
            Color piel, pelo;
            double velocidad, remate, presicion;
            boolean portero;
            Posicion posicion;

            public JugadorImpl(String nombre, int numero, Color piel, Color pelo,
                    double velocidad, double remate, double presicion, boolean portero) {
                this.nombre = nombre;
                this.numero = numero;
                this.piel = piel;
                this.pelo = pelo;
                this.velocidad = velocidad;
                this.remate = remate;
                this.presicion = presicion;
                this.portero = portero;
            }

            public String getNombre() {
                return nombre;
            }

            public Color getColorPiel() {
                return piel;
            }

            public Color getColorPelo() {
                return pelo;
            }

            public int getNumero() {
                return numero;
            }

            public boolean esPortero() {
                return portero;
            }

            public double getVelocidad() {
                return velocidad;
            }

            public double getRemate() {
                return remate;
            }

            public double getPresicion() {
                return presicion;
            }
        }

        public JugadorDetalle[] getJugadores() {
            return new JugadorDetalle[]{
                        new JugadorImpl("Van Peten", 1, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 1.0d, 1.0d, true),
                        new JugadorImpl("Van a Verle", 2, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.5d, 0.56d, false),
                        new JugadorImpl("Van Tigre", 3, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.5d, 0.6d, false),
                        new JugadorImpl("R Puuma", 4, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 1.0d, 0.79d, false),
                        new JugadorImpl("De Blaind", 5, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.65d, 0.58d, false),
                        new JugadorImpl("El Ricard", 6, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.83d, 0.71d, false),
                        new JugadorImpl("Pouters", 7, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.59d, 0.77d, false),
                        new JugadorImpl("Ouvermarxx", 8, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.69d, 0.6d, false),
                        new JugadorImpl("Van Pasta", 9, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 1.0d, 1.0d, false),
                        new JugadorImpl("Bullit", 10, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 1.0d, 0.88d, false),
                        new JugadorImpl("E. Puuma", 11, new Color(255, 200, 150), new Color(50, 0, 0), 1.0d, 0.64d, 0.61d, false)
                    };
        }
    }
    TacticaDetalle detalle = new TacticaDetalleImpl();

    public TacticaDetalle getDetalle() {
        return detalle;
    }

    public Posicion[] getPosicionSaca(SituacionPartido sp) {
        return alineacion2;
    }

    public Posicion[] getPosicionRecive(SituacionPartido sp) {
        return alineacion3;
    }
    //Lista de comandos
    LinkedList<Comando> comandos = new LinkedList<Comando>();
    List<Integer> availablePlayers; // Players who can be used for the strategy
    List<Integer> dangerousEnemies;
    Posicion[] enemies;
    Posicion[] myPlayers;
    boolean enRegate;
    int faseRegate = 1;
    Map<Integer, Posicion> posicionBalon = new HashMap<Integer, Posicion>();

    public List<Comando> ejecutar(SituacionPartido sp) {
        //Limpia la lista de comandos
        comandos.clear();
        //Actualizar posicion de jugadores
        udpatePositionPlayers(sp.balon(), sp.misJugadores());
        //Cubrir a jugadores potencialmente peligrosos solo cuando yo no saco
        if (!sp.saco()) {
            cubrirJugadoresPeligrosos(sp);
        }

        //Si no saca el rival
        if (!sp.sacaRival()) {
            //Obtiene los datos de recuperacion del balon
            int[] recuperadores = sp.getRecuperacionBalon();
            //Si existe posibilidad de recuperar el balon
            if (recuperadores.length > 1) {
                //Obtiene las coordenadas del balon en el instante donde se puede recuperar el balon
                double[] posRecuperacion = sp.getTrayectoria(recuperadores[0]);
                //Recorre la lista de jugadores que pueden recuperar
                for (int i = 1; i < recuperadores.length; i++) {
                    //Ordena a los jugadores recuperadores que se ubique en la posicion de recuperacion
                    if (i != 0) {
                        comandos.add(new ComandoIrA(recuperadores[i], new Posicion(posRecuperacion[0], posRecuperacion[1])));
                    }
                }
            }
        }

        //Recorre la lista de mis jugadores que pueden rematar o pasar en definitiva que pueden hacer algo con el balon
        for (int i : sp.puedenRematar()) {
            //Si el jugador es de indice 0 (portero) que despeje
            if (i != 0) {
                double distancia = distanciaPorteria(sp, true);
                // Si estamos cerca de la porteria
                if (distancia < 22) {
                    tirarAPuerta(sp);
                } else {
                    dondePasar(sp);
                }



            }
        }

        zonaPortero(sp);
        //Retorna la lista de comandos
        return comandos;
    }

    private void dondePasar(SituacionPartido sp) {
        boolean[] defensa, medio, delantero;
        defensa = new boolean[alineacion1.length];
        medio = new boolean[alineacion1.length];
        delantero = new boolean[alineacion1.length];

        //DEFINIMOS EN QUE LINEA ESTA CADA JUGADOR
        for (int i = 0; i < alineacion1.length; ++i) {
            defensa[i] = i >= 1 && i <= 4;
            medio[i] = i >= 5 && i <= 7;
            delantero[i] = i >= 8 && i <= 10;
        }
        int llevaBalon[] = sp.puedenRematar();

        //QUIEN LLEVA EL BALON
        if (defensa[llevaBalon[0]]) {
            pasarDesdeDefensa(sp);
        } else if (medio[llevaBalon[0]]) { //UN CENTROCAMPISTA
            pasarDesdeMedios(sp);
        } else { // UN DELANTERO
            pasarDelanteros(sp);
        }

    }

    private void pasarDesdeDefensa(SituacionPartido sp) {
        Posicion[] jugadoresPosicion = sp.misJugadores();
        int jugadores[] = sp.getRecuperacionBalon();

        int llevaBalon[] = sp.puedenRematar();
        //Si son los centrales abrir a las bandas
        if (llevaBalon[0] == 3 || llevaBalon[0] == 4) {
            if (tengoRivalCerca(sp)) {
                comandos.add(new ComandoGolpearBalon(llevaBalon[0], Constantes.centroArcoSup, 1, 40));
            } else {
                double distanciaAlJugadorDeBanda = 0;
                int jugadorDestino = 0;
                if (jugadores.length>1) {
                    if (bandaIzquierda(sp.balon())) {
                        distanciaAlJugadorDeBanda = jugadoresPosicion[jugadores[1]].distancia(jugadoresPosicion[7]);
                        jugadorDestino = 7;
                        comandos.add(new ComandoIrA(jugadorDestino, jugadoresPosicion[llevaBalon[0]]));
                        comandos.add(new ComandoGolpearBalon(llevaBalon[0], jugadoresPosicion[jugadorDestino],
                                calcularFuerza(distanciaAlJugadorDeBanda),
                                calcularAngulo(distanciaAlJugadorDeBanda)));
                    } else {
                        distanciaAlJugadorDeBanda = jugadoresPosicion[jugadores[1]].distancia(jugadoresPosicion[6]);
                        jugadorDestino = 6;
                        comandos.add(new ComandoIrA(jugadorDestino, jugadoresPosicion[llevaBalon[0]]));
                        comandos.add(new ComandoGolpearBalon(llevaBalon[0], jugadoresPosicion[jugadorDestino],
                                calcularFuerza(distanciaAlJugadorDeBanda),
                                calcularAngulo(distanciaAlJugadorDeBanda)));
                    }
                } 
            }
        } else {
            if (bandaIzquierda(sp.balon())) {
                comandos.add(new ComandoGolpearBalon(llevaBalon[0], jugadoresPosicion[7], 1, 10));
            } else {
                comandos.add(new ComandoGolpearBalon(llevaBalon[0], jugadoresPosicion[6], 1, 10));
            }
        }

    }

    private void pasarDesdeMedios(SituacionPartido sp) {
        Posicion[] jugadoresPase = sp.misJugadores();
        int llevaBalon[] = sp.puedenRematar();
        int jugadores[] = sp.getRecuperacionBalon();
        Random r = new Random();
        double distanciaAlJugadorDeBanda = 0;
        int jugadorDestino = 0;
        if (tengoRivalCerca(sp) && !rivalPorDetras(sp)) {
            if (bandaIzquierda(sp.balon())) {
                if (llevaBalon[0] == 5) {
                    jugadorDestino = 7;
                    distanciaAlJugadorDeBanda = jugadoresPase[jugadores[1]].distancia(jugadoresPase[jugadorDestino]);
                    comandos.add(new ComandoIrA(7, jugadoresPase[llevaBalon[0]]));
                    comandos.add(new ComandoGolpearBalon(llevaBalon[0], jugadoresPase[7],
                            calcularFuerza(distanciaAlJugadorDeBanda),
                            calcularAngulo(distanciaAlJugadorDeBanda)));
                } else {
                    jugadorDestino = 10;
                    distanciaAlJugadorDeBanda = jugadoresPase[jugadores[1]].distancia(jugadoresPase[jugadorDestino]);
                    comandos.add(new ComandoIrA(10, jugadoresPase[llevaBalon[0]]));
                    comandos.add(new ComandoGolpearBalon(llevaBalon[0], jugadoresPase[10],
                            calcularFuerza(distanciaAlJugadorDeBanda),
                            calcularAngulo(distanciaAlJugadorDeBanda)));

                }
            } else {
                if (llevaBalon[0] == 5) {
                    jugadorDestino = 6;
                    distanciaAlJugadorDeBanda = jugadoresPase[jugadores[1]].distancia(jugadoresPase[jugadorDestino]);
                    comandos.add(new ComandoIrA(6, jugadoresPase[llevaBalon[0]]));
                    comandos.add(new ComandoGolpearBalon(llevaBalon[0], jugadoresPase[6],
                            calcularFuerza(distanciaAlJugadorDeBanda),
                            calcularAngulo(distanciaAlJugadorDeBanda)));
                } else {
                    jugadorDestino = 9;
                    distanciaAlJugadorDeBanda = jugadoresPase[jugadores[1]].distancia(jugadoresPase[jugadorDestino]);
                    comandos.add(new ComandoIrA(9, jugadoresPase[llevaBalon[0]]));
                    comandos.add(new ComandoGolpearBalon(llevaBalon[0], jugadoresPase[9],
                            calcularFuerza(distanciaAlJugadorDeBanda),
                            calcularAngulo(distanciaAlJugadorDeBanda)));
                }
            }
        } else {
            //avanzar a porteria o tirar
            if (jugadoresPase[llevaBalon[0]].distancia(Constantes.centroArcoSup) < Constantes.ANCHO_AREA_GRANDE + 5) {
                comandos.add(new ComandoGolpearBalon(llevaBalon[0], Constantes.centroArcoSup, 1, 12 + r.nextInt(5)));
            } else {
                comandos.add(new ComandoGolpearBalon(llevaBalon[0], new Posicion(jugadoresPase[llevaBalon[0]].getX(), Constantes.LARGO_CAMPO_JUEGO / 2), 0.4, 0));
            }
        }
    }

    private void pasarDelanteros(SituacionPartido sp) {
        Posicion[] jugadoresPase = sp.misJugadores();
        int llevaBalon[] = sp.puedenRematar();

        if (tengoRivalCerca(sp) && !rivalPorDetras(sp)) {
            if (jugadoresPase[llevaBalon[0]].getX() > coordenadasRivalCerca(sp).getX()) {
                comandos.add(new ComandoIrA(llevaBalon[0], new Posicion(jugadoresPase[llevaBalon[0]].getX(), Constantes.ANCHO_CAMPO_JUEGO)));

            } else {
                comandos.add(new ComandoIrA(llevaBalon[0], new Posicion(jugadoresPase[llevaBalon[0]].getX(), -Constantes.ANCHO_CAMPO_JUEGO)));
            }
        } else {
            //avanzar a porteria o tirar
            if (jugadoresPase[llevaBalon[0]].distancia(Constantes.centroArcoSup) < Constantes.ANCHO_AREA_GRANDE + 5) {
                tirarAPuerta(sp);
            } else {
                if (jugadoresPase[llevaBalon[0]].getY() > Constantes.LARGO_CAMPO_JUEGO / 2 - 15) {
                    comandos.add(new ComandoIrA(8, Constantes.penalSup));
                    comandos.add(new ComandoGolpearBalon(llevaBalon[0], new Posicion(Constantes.penalSup.getX(), Constantes.penalSup.getY()), 0.9, 15));
                } else {
//		        	if (jugadoresPase[llevaBalon[0]].getY() > Constantes.LARGO_CAMPO_JUEGO/2 -20 ){
//		        		comandos.add(new ComandoGolpearBalon(llevaBalon[0],Constantes.centroArcoSup,0.5,0));
//		        	}else{
                    comandos.add(new ComandoGolpearBalon(llevaBalon[0], new Posicion(jugadoresPase[llevaBalon[0]].getX(), jugadoresPase[llevaBalon[0]].getY() + 10), 0.5, 0));
//		        	}
                }
            }
        }

    }

    private boolean bandaIzquierda(Posicion balon) {
        if (balon.getX() < 0) {
            return true;
        } else {
            return false;
        }

    }

    private boolean tengoRivalCerca(SituacionPartido sp) {
        int jugadores[] = sp.getRecuperacionBalon();
        Posicion posicionJugadores[] = sp.misJugadores();

        Posicion posicionRivales[] = sp.rivales();

        if (jugadores.length > 1) {
            if (posicionRivales != null) {
                for (Posicion i : posicionRivales) {
                    double distancia = posicionJugadores[jugadores[1]].distancia(i);
                    double distanciaPorteriaPropia = distanciaPorteria(sp, false);
                    if (distancia < 9 && distanciaPorteriaPropia < 30) {
                        comandos.add(new ComandoGolpearBalon(jugadores[1], Constantes.centroArcoSup, 1, 40));
                    } else if (distancia < 9) {
                        return true;
                    }
                }
            }
        } else {
            return false;
        }
        return false;
    }

    private boolean rivalPorDetras(SituacionPartido sp) {
        int jugadores[] = sp.getRecuperacionBalon();
        Posicion posicionJugadores[] = sp.misJugadores();

        Posicion posicionRivales[] = sp.rivales();

        if (jugadores.length > 1) {
            if (posicionRivales != null) {
                for (Posicion i : posicionRivales) {
                    double distancia = posicionJugadores[jugadores[1]].distancia(i);
                    if (distancia < 4 && posicionJugadores[jugadores[1]].getY() > i.getY()) {
                        if (posicionJugadores[jugadores[1]].getY() > i.getY()) {
                            return true;
                        } else {
                            return false;
                        }
                    }
                }
            }
        } else {
            return false;
        }
        return false;
    }

    private Posicion coordenadasRivalCerca(SituacionPartido sp) {
        int jugadores[] = sp.getRecuperacionBalon();
        Posicion posicionJugadores[] = sp.misJugadores();
        Posicion posicionRivales[] = sp.rivales();
        Posicion rivalMasCerca = new Posicion();

        if (jugadores.length > 1) {
            if (posicionRivales != null) {
                for (Posicion i : posicionRivales) {
                    double distancia = posicionJugadores[jugadores[1]].distancia(i);
                    if (distancia < 8) {
                        rivalMasCerca = i;
                        return rivalMasCerca;
                    }
                }
            }
        } else {
            return rivalMasCerca;
        }
        return rivalMasCerca;
    }

    private void cubrirJugadoresPeligrosos(SituacionPartido sp) {
        availablePlayers = new ArrayList<Integer>();
        dangerousEnemies = new ArrayList<Integer>();
        myPlayers = new Posicion[alineacion1.length];
        enemies = new Posicion[alineacion1.length];


        availablePlayers.clear();
        for (int i = 0; i < 11; ++i) {
            if (i != 1 && i != 2) {
                availablePlayers.add(i);
            }
        }
        Posicion[] temp = sp.rivales();
        for (int i = 0; i < temp.length; ++i) {
            enemies[i] = new Posicion(temp[i]);
        }

        temp = sp.misJugadores();
        for (int i = 0; i < temp.length; ++i) {
            myPlayers[i] = new Posicion(temp[i]);
        }

        dangerousEnemies.clear();
        Posicion miCampo = new Posicion(0, -Constantes.LARGO_CAMPO_JUEGO / 3);
        while (enemies.length != dangerousEnemies.size()) {
            double minDist = 1000;
            int minJ = 0;
            for (int j = enemies.length - 1; j >= 0; --j) {
                if (dangerousEnemies.contains(new Integer(j))) {
                    continue;
                }
                //Comprobamos que el rival está dentro del terreno de juego
                if (enemies[j].isDentroCampoJuego(0.0)) {
                    double dist = miCampo.distancia(enemies[j]);
                    if (dist < minDist) {
                        minDist = dist;
                        minJ = j;
                    }
                }
            }
            dangerousEnemies.add(new Integer(minJ));
        }

        for (int j : dangerousEnemies) {
            int iMin = -1;
            double distMin = 0;
            for (int i : availablePlayers) {
                if (i == 1 || i == 2 || i == 3 || i == 4) {
                    double dist = enemies[j].distancia(myPlayers[i]);
                    if (dist < distMin || iMin < 0) {
                        iMin = i;
                        distMin = dist;
                    }
                }
            }
            if (iMin < 0) {
                break;
            }

            Posicion positionUpdated = new Posicion(enemies[j].getX(), enemies[j].getY()).moverPosicion(0, -1);
            comandos.add(new ComandoIrA(iMin, positionUpdated));
            availablePlayers.remove(new Integer(iMin));
        }
    }

    private void udpatePositionPlayers(Posicion balon, Posicion[] misJugadores) {
        Posicion positionUpdated[] = new Posicion[]{};
        //Zona 1
        if (balon.getY() <= -26 && balon.getY() > -52.5) {
            positionUpdated = new Posicion[]{
                        new Posicion(0.2595419847328244, -50.41044776119403),
                        new Posicion(19.97202797202797, -36.82126696832579),
                        new Posicion(-20.923076923076923, -35.8710407239819),
                        new Posicion(7.608391608391608, -36.34615384615385),
                        new Posicion(-10.937062937062937, -34.920814479638004),
                        new Posicion(0, 0),
                        new Posicion(30.909090909090907, -18.054298642533936),
                        new Posicion(-31.146853146853147, -17.816742081447966),
                        new Posicion(0.23776223776223776, 9.502262443438914),
                        new Posicion(31.146853146853147, 3.3257918552036196),
                        new Posicion(-31.86013986013986, 1.6628959276018098)
                    };
        }
        //Zona 2
        if (balon.getY() <= 0 && balon.getY() > -26) {
            positionUpdated = new Posicion[]{
                        new Posicion(0.2595419847328244, -50.41044776119403),
                        new Posicion(19.97202797202797, -36.82126696832579),
                        new Posicion(-20.923076923076923, -35.8710407239819),
                        new Posicion(7.608391608391608, -36.34615384615385),
                        new Posicion(-10.937062937062937, -34.920814479638004),
                        new Posicion(0, 0),
                        new Posicion(30.909090909090907, -7.601809954751132),
                        new Posicion(-32.0979020979021, -11.64027149321267),
                        new Posicion(-0.4755244755244755, 26.606334841628957),
                        new Posicion(30.909090909090907, 16.131221719457013),
                        new Posicion(-32.81118881118881, 16.391402714932127)
                    };
        }
        //Zona 3
        if (balon.getY() > 0 && balon.getY() < 26) {
            positionUpdated = new Posicion[]{
                        new Posicion(0.2595419847328244, -50.41044776119403),
                        new Posicion(25.44055944055944, -27.556561085972852),
                        new Posicion(-27.81818181818182, -27.31900452488688),
                        new Posicion(9.272727272727272, -31.119909502262445),
                        new Posicion(-10.461538461538462, -30.407239819004527),
                        new Posicion(0, 0),
                        new Posicion(30.433566433566433, 2.6131221719457014),
                        new Posicion(-30.67132867132867, 4.513574660633484),
                        new Posicion(0.0, 22.092760180995477),
                        new Posicion(32.33566433566433, 26.93212669683258),
                        new Posicion(-32.33566433566433, 26.606334841628957)
                    };
        }
        //Zona 4
        if (balon.getY() >= 26 && balon.getY() <= 52.5) {
            positionUpdated = new Posicion[]{
                        new Posicion(0.2595419847328244, -50.41044776119403),
                        new Posicion(25.916083916083913, -13.065610859728507),
                        new Posicion(-27.58041958041958, -14.96606334841629),
                        new Posicion(9.034965034965035, -25.18099547511312),
                        new Posicion(-11.412587412587413, -23.755656108597286),
                        new Posicion(0, 0),
                        new Posicion(29.72027972027972, 18.766968325791854),
                        new Posicion(-32.0979020979021, 20.429864253393667),
                        new Posicion(0.0, 36.82126696832579),
                        new Posicion(10.20979020979021, 38.80995475113122),
                        new Posicion(-10.97202797202797, 38.95927601809955)
                    };
        }
        //Ordena a cada jugador que se ubique segun la alineacion actualizada
        if (positionUpdated.length > 0) {
            for (int i = 0; i < misJugadores.length; i++) {
                comandos.add(new ComandoIrA(i, positionUpdated[i]));
            }
        }
    }

    private void tirarAPuerta(SituacionPartido sp) {
        Random r = new Random();
        int llevaBalon[] = sp.puedenRematar();
        if (r.nextBoolean()) {
            //Ordena que debe rematar al centro del arco
            comandos.add(new ComandoGolpearBalon(llevaBalon[0], Constantes.centroArcoSup, 1, 9 + r.nextInt(2)));
        } else if (r.nextBoolean()) {
            //Ordena que debe rematar al poste derecho
            comandos.add(new ComandoGolpearBalon(llevaBalon[0], Constantes.posteDerArcoSup, 1, 9 + r.nextInt(2)));
        } else {
            //Ordena que debe rematar al poste izquierdo
            comandos.add(new ComandoGolpearBalon(llevaBalon[0], Constantes.posteIzqArcoSup, 1, 9 + r.nextInt(2)));
        }
    }

    private double distanciaPorteria(SituacionPartido sp, boolean rival) {
        double coordenadas[] = sp.getTrayectoria(sp.iteracion());
        Posicion balon = new Posicion(coordenadas[0], coordenadas[1]);
        Posicion pos;
        if (rival) {
            pos = Constantes.centroArcoSup;
        } else {
            pos = Constantes.centroArcoInf;
        }
        double distancia = pos.distancia(balon);

        return distancia;
    }

    private void zonaPortero(SituacionPartido s) {

        posicionBalon.put(s.iteracion(), s.balon());


        if (posicionBalon.size() > 3) {

            Posicion p1 = posicionBalon.get(s.iteracion() - 2);
            Posicion p2 = posicionBalon.get(s.iteracion() - 1);
            Posicion p3 = posicionBalon.get(s.iteracion());


            if ((p3.getX() < (Constantes.LARGO_AREA_CHICA / 2)) && (p3.getX() > -(Constantes.LARGO_AREA_CHICA / 2))) {

//        		 System.out.println("RANGO!");

                if (p3.getX() < p2.getX()) {
                    if (p2.getX() < p1.getX()) {
//		    			 System.out.println("IZQUIERDA!");
                        comandos.add(new ComandoIrA(0, new Posicion(s.balon().getX(), Constantes.centroArcoInf.getY())));
                    }
                }


                if (p3.getX() > p2.getX()) {
                    if (p2.getX() > p1.getX()) {
//		    			System.out.println("DERECHA!");
                        comandos.add(new ComandoIrA(0, new Posicion(s.balon().getX(), Constantes.centroArcoInf.getY())));
                    }
                }

                posicionBalon.clear();
            }

        }


//    	if((s.balon().getX()>Constantes.posteIzqArcoInf.getX()) && (s.balon().getX()<Constantes.posteDerArcoInf.getX())){
//    		comandos.add(new ComandoIrA(0,new Posicion(s.balon().getX(),Constantes.centroArcoInf.getY()+2)));
//    	}


        comandos.add(new ComandoGolpearBalon(0, Constantes.penalInf, 1, true));

//    	if (bandaIzquierda(posicionPortero)) {
//			double distancia = jugadoresPase[0].distancia(jugadoresPase[6]);
//			comandos.add(new ComandoGolpearBalon(0, s.misJugadores()[7],calcularFuerza(distancia),calcularFuerza(distancia)));
//		} else {
//			double distancia = jugadoresPase[0].distancia(jugadoresPase[6]);
//			comandos.add(new ComandoGolpearBalon(0, s.misJugadores()[6], calcularFuerza(distancia),calcularFuerza(distancia)));
//		}

    }

    private double calcularAngulo(double distanciaAlJugador) {
        double fuerza = 0;
        if (distanciaAlJugador > 30) {
            fuerza = 1;
        } else if (distanciaAlJugador > 20) {
            fuerza = 0.8;
        } else {
            fuerza = 0.6;
        }
        return fuerza;
    }

    private double calcularFuerza(double distanciaAlJugador) {
        double angulo = 0;
        if (distanciaAlJugador > 30) {
            angulo = 1;
        } else if (distanciaAlJugador > 20) {
            angulo = 0.8;
        } else {
            angulo = 0.6;
        }
        return angulo;
    }
}
